package net.sk.china.platform.service.impl.city;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.sk.china.common.exception.TalkException;
import net.sk.china.common.utils.RedisUtil;
import net.sk.china.platform.dao.city.CityMenuDao;
import net.sk.china.platform.model.city.CityMenu;
import net.sk.china.platform.request.city.CityMenuRequest;
import net.sk.china.platform.request.city.CityMenuSearchRequest;
import net.sk.china.platform.response.menu.MenuCheckResponse;
import net.sk.china.platform.service.city.CityMenuService;
import net.sk.china.platform.service.system.SystemCityService;
import net.sk.china.platform.utils.MenuCheckTreeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * CityMenuServiceImpl 接口实现
 * +----------------------------------------------------------------------
 * | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2018-2024 聊来All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">apache</a> )
 * +----------------------------------------------------------------------
 * | @Author: 聊来 <18970881148@qq.com>
 * +----------------------------------------------------------------------
 * | DateTime: 2024/6/12 09:32
 * +----------------------------------------------------------------------
 */

@Service
public class CityMenuServiceImpl extends ServiceImpl<CityMenuDao, CityMenu> implements CityMenuService {

    @Resource
    private CityMenuDao dao;

    private static final String CACHE_LIST_KEY = "cityMenuList";

    private final RedisUtil redisUtil;

    private final SystemCityService systemCityService;

    public CityMenuServiceImpl(RedisUtil redisUtil, SystemCityService systemCityService) {
        this.redisUtil = redisUtil;
        this.systemCityService = systemCityService;
    }

    /**
     * 列表
     * @param request 请求参数
     * @return {@code List<CityMenu>}
     */
    @Override
    public List<CityMenu> getList(CityMenuSearchRequest request) {
        LambdaQueryWrapper<CityMenu> query = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(request.getName())) {
            query.like(CityMenu::getName, request.getName());
        }
        if (StrUtil.isNotEmpty(request.getMenuType())) {
            query.eq(CityMenu::getName, request.getMenuType());
        }
        query.eq(CityMenu::getIsDelete, false);
        query.orderByDesc(CityMenu::getSort);
        query.orderByAsc(CityMenu::getId);

        return dao.selectList(query);
    }

    /**
     * 新增菜单
     * @param request 菜单参数
     * @return {@code boolean}
     */
    @Override
    public boolean add(CityMenuRequest request) {
        String c = "C";
        if (request.getMenuType().equals(c) && StrUtil.isEmpty(request.getComponent())) {
            throw new TalkException("菜单类型的组件路径不能为空");
        }
        String a = "A";
        if (request.getMenuType().equals(a) && StrUtil.isEmpty(request.getPerms())) {
            throw new TalkException("按钮类型的权限表示不能为空");
        }
        CityMenu cityMenu = new CityMenu();
        request.setId(null);
        BeanUtils.copyProperties(request, cityMenu);
        boolean save = save(cityMenu);
        if (save) {
            redisUtil.delete(CACHE_LIST_KEY);
        }
        return save;
    }


    /**
     * 根据id删除菜单
     * @param id 菜单id
     * @return {@code boolean}
     */
    @Override
    public boolean deleteById(Integer id) {
        CityMenu cityMenu = getInfoById(id);
        cityMenu.setIsDelete(true);
        String a = "A";
        if (cityMenu.getMenuType().equals(a)) {
            boolean update = updateById(cityMenu);
            if (update) {
                redisUtil.delete(CACHE_LIST_KEY);
            }
            return update;
        }
        List<CityMenu> childList = findAllChildListByPid(id);
        if (CollUtil.isEmpty(childList)) {
            boolean update = updateById(cityMenu);
            if (update) {
                redisUtil.delete(CACHE_LIST_KEY);
            }
            return update;
        }
        childList.forEach(e -> e.setIsDelete(true));
        childList.add(cityMenu);
        boolean updateBatch = updateBatchById(childList);
        if (updateBatch) {
            redisUtil.delete(CACHE_LIST_KEY);
        }
        return updateBatch;
    }

    /**
     * 修改菜单
     * @param request 菜单参数
     * @return {@code boolean}
     */
    @Override
    public boolean edit(CityMenuRequest request) {
        if (ObjectUtil.isNull(request.getId())) {
            throw new TalkException("系统菜单id不能为空");
        }
        String c = "C";
        if (request.getMenuType().equals(c) && StrUtil.isEmpty(request.getComponent())) {
            throw new TalkException("菜单类型的组件路径不能为空");
        }
        String a = "A";
        if (request.getMenuType().equals(a) && StrUtil.isEmpty(request.getPerms())) {
            throw new TalkException("按钮类型的权限表示不能为空");
        }
        CityMenu cityMenu = new CityMenu();
        BeanUtils.copyProperties(request, cityMenu);
        boolean update = updateById(cityMenu);
        if (update) {
            redisUtil.delete(CACHE_LIST_KEY);
        }
        return update;
    }

    /**
     * 获取菜单详情
     * @param id 菜单id
     * @return {@code CityMenu}
     */
    @Override
    public CityMenu getInfo(Integer id) {
        CityMenu CityMenu = getInfoById(id);
        CityMenu.setIsDelete(null);
        CityMenu.setCreateTime(null);
        CityMenu.setUpdateTime(null);
        return CityMenu;
    }

    /**
     * 修改菜单显示状态
     * @param id 菜单id
     * @return {@code boolean}
     */
    @Override
    public boolean updateShowStatus(Integer id) {
        CityMenu cityMenu = getInfoById(id);
        cityMenu.setIsShow(!cityMenu.getIsShow());
        boolean update = updateById(cityMenu);
        if (update) {
            redisUtil.delete(CACHE_LIST_KEY);
        }
        return update;
    }

    /**
     * 菜单缓存树
     * @return {@code List<MenuCheckResponse>}
     */
    @Override
    public List<MenuCheckResponse> getCacheTree() {
        List<CityMenu> menuList = getCacheList();
        List<MenuCheckResponse> voList = menuList.stream().map(e -> {
            MenuCheckResponse menuCheckResponse = new MenuCheckResponse();
            BeanUtils.copyProperties(e, menuCheckResponse);
            return menuCheckResponse;
        }).collect(Collectors.toList());
        MenuCheckTreeUtil menuTree = new MenuCheckTreeUtil(voList);
        return menuTree.buildTree();
    }

    /**
     * 获取详细信息
     * @param id 菜单id
     * @return {@code CityMenu}
     */
    private CityMenu getInfoById(Integer id) {
        CityMenu city = getById(id);
        if (ObjectUtil.isNull(city) || city.getIsDelete()) {
            throw new TalkException("分站系统菜单不存在");
        }
        return city;
    }

    /**
     * 根据菜单id获取所有下级对象
     * @param pid 菜单id
     * @return {@code List<CityMenu>}
     */
    private List<CityMenu> findAllChildListByPid(Integer pid) {
        LambdaQueryWrapper<CityMenu> query = new LambdaQueryWrapper<>();
        query.eq(CityMenu::getPid, pid);
        query.eq(CityMenu::getIsDelete, false);

        return dao.selectList(query);
    }

    /**
     * 获取菜单缓存列表
     * @return {@code List<CityMenu>}
     */
    private List<CityMenu> getCacheList() {
        if (redisUtil.exists(CACHE_LIST_KEY)) {
            return redisUtil.get(CACHE_LIST_KEY);
        }
        LambdaQueryWrapper<CityMenu> query = new LambdaQueryWrapper<>();
        query.eq(CityMenu::getIsDelete, false);
        List<CityMenu> cityMenuList = dao.selectList(query);
        redisUtil.set(CACHE_LIST_KEY, cityMenuList);

        return cityMenuList;
    }
}
